﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Navigation;
using C1.WPF;
using C1.WPF.Extended;
using System.Windows.Media.Animation;
using System.Reflection;
using System.Threading;
using System.Globalization;

namespace ControlExplorer
{
    public partial class SamplePage : Page
    {
        const string ROOT_PATH = "[YourDocuments]\\ComponentOne Samples\\Studio for Silverlight\\";

        public SamplePage()
        {
            InitializeComponent();
            Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-Hans");
        }

        // Executes when the user navigates to this page.
        public void OnNavigatedTo(string fragment)
        {
            //var fragment = Uri.UnescapeDataString(uri.OriginalString.Split('#')[1]);
            fragment = "/" + Uri.UnescapeDataString(fragment);
            var feature = MainViewModel.Instance.Features.FirstOrDefault(f => f.Link.OriginalString == fragment);
            if (feature != null)
            {
                try
                {
                    Title = feature.Control.Name + " - " + feature.Name;
                    var assembly = Assembly.LoadFrom(feature.AssemblyName);
                    feature.Sample = assembly.CreateInstance(feature.FullDemoControlTypeName) as FrameworkElement;

                    //                    XamlPathContainer.Visibility = System.Windows.Visibility.Visible;
                    //                    if (!string.IsNullOrEmpty(feature.XamlPath))
                    //                    {
                    //                        XamlPathTextBox.Text = ROOT_PATH + feature.XamlPath;
                    //                    }
                    //                    else
                    //                    {
                    //                        XamlPathContainer.Visibility = System.Windows.Visibility.Collapsed;
                    //                    }
                    //
                    //                    SolutionPathContainer.Visibility = System.Windows.Visibility.Visible;
                    //                    if (!string.IsNullOrEmpty(feature.SolutionPath))
                    //                    {
                    //                        SolutionPathTextBox.Text = ROOT_PATH + feature.SolutionPath;
                    //                    }
                    //                    else
                    //                    {
                    //                        SolutionPathContainer.Visibility = System.Windows.Visibility.Collapsed;
                    //                    }
                    //
                    //                    if (!string.IsNullOrEmpty(feature.Control.AssemblyName))
                    //                    {
                    //                        ControlAssemblyContainer.Visibility = Visibility.Visible;
                    //                        ControlAssembly.Text = feature.Control.AssemblyName + ".dll";
                    //                    }
                    //                    else
                    //                    {
                    //                        ControlAssemblyContainer.Visibility = Visibility.Collapsed;
                    //                    }

                    properties.AvailableEditors.Insert(0, new TimeSpanEditor());
                    properties.AvailableEditors.Insert(0, new NumericEditor());
                    properties.AvailableEditors.Insert(0, new ReadOnlyImageSourceEditor());
                    properties.AvailableEditors.Insert(0, new CornerRadiusEditor());
                    properties.PropertyAttributes.Clear();
                    LoadCollection<PropertyAttribute>(properties.PropertyAttributes, feature.Properties);
                    //LoadCollection<MethodAttribute>(properties.MethodAttributes, feature.Actions);

                    DataContext = feature;

                    Dispatcher.BeginInvoke(new Action(() =>
                        {
                            this.UpdateLayout();
                            var item = FindItem(tree, feature);
                            if (item != null)
                            {
                                item.IsSelected = true;
                                // scroll item into view
                                IList<DependencyObject> list = new List<DependencyObject>();
                                VTreeHelper.GetChildrenOfType(tree, typeof(ScrollViewer), ref list);
                                if (list.Count > 0)
                                {
                                    ScrollViewer scv = list[0] as ScrollViewer;
                                    Point point = item.TransformToVisual(scv).Transform(new Point(scv.HorizontalOffset, scv.VerticalOffset));
                                    Rect rect = new Rect(point, new Point(point.X + item.ActualWidth, point.Y + item.ActualHeight));
                                    if (scv.VerticalOffset > rect.Top)
                                    {
                                        scv.ScrollToVerticalOffset(rect.Top);
                                    }
                                    else if (scv.VerticalOffset < rect.Bottom - scv.ViewportHeight)
                                    {
                                        scv.ScrollToVerticalOffset(rect.Bottom - scv.ViewportHeight);
                                    }
                                }
                            }
                        }), System.Windows.Threading.DispatcherPriority.Loaded);
                }
                catch { }
            }
        }

        protected void OnNavigatedFrom(NavigationEventArgs e)
        {
            FeatureDescription feature = DataContext as FeatureDescription;
            if (feature != null)
            {
                IDisposable disposable = feature.Sample as IDisposable;

                if (disposable != null)
                {
                    // that allows explicitly release resources (for example, close non modal windows)
                    disposable.Dispose();
                }
            }
        }

        private C1TreeViewItem FindItem(C1HierarchicalPresenter tree, FeatureDescription feature)
        {
            var treeViewItem = tree.ItemContainerGenerator.ContainerFromItem(feature) as C1TreeViewItem;
            if (treeViewItem != null)
            {
                return treeViewItem;
            }
            else
            {
                foreach (var item in tree.Items)
                {
                    var tvi = tree.ItemContainerGenerator.ContainerFromItem(item) as C1TreeViewItem;
                    if (tvi.HasItems)
                    {
                        treeViewItem = FindItem(tvi, feature);
                        if (treeViewItem != null)
                            return treeViewItem;
                    }
                }
            }
            return null;
        }

        private void LoadCollection<T>(Collection<T> list, IEnumerable data)
        {
            if (data != null)
                foreach (var item in data)
                {
                    list.Add((T)item);
                }
        }

        private void tree_ItemPrepared(object sender, C1.WPF.ItemPreparedEventArgs e)
        {
            (e.Element as C1TreeViewItem).SetBinding(C1TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Source = e.Item, Mode = BindingMode.TwoWay });
        }

        private void tree_ItemClick(object sender, SourcedEventArgs e)
        {
            var feature = (e.Source as C1TreeViewItem).DataContext as FeatureDescription;
            try
            {
                if (feature.SubFeatures.Count() == 0)
                {
                    NavigationService.Navigate(feature.Link);
                }
                else
                {
                    feature.IsExpanded = !feature.IsExpanded;
                }
            }
            catch { }
        }
        private void properties_AddingPropertyBox(object sender, ChangingPropertyBoxEventArgs e)
        {
            e.PropertyBox.Style = Resources["PropertiesPropertyBox"] as Style;
        }
    }
}
